package com.xinqi.modules.sys.feedback.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.base.response.R;
import com.xinqi.common.base.utils.spring.Spring;
import com.xinqi.common.core.constant.ChatRemindConstants;
import com.xinqi.common.core.enums.ChatRemindTypeEnum;
import com.xinqi.common.core.enums.FeedbackModeEnum;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.core.utils.StringUtils;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.modules.chat.chat.official.client.ChatRemindContentClient;
import com.xinqi.modules.chat.chat.official.dto.req.ChatRemindContentCreateDTO;
import com.xinqi.modules.sys.feedback.convert.FeedbackConvert;
import com.xinqi.modules.sys.feedback.domain.FeedbackEntity;
import com.xinqi.modules.sys.feedback.dto.req.FeedbackCreateDTO;
import com.xinqi.modules.sys.feedback.dto.req.FeedbackDeleteDTO;
import com.xinqi.modules.sys.feedback.dto.req.FeedbackGrantDTO;
import com.xinqi.modules.sys.feedback.dto.req.FeedbackQueryDTO;
import com.xinqi.modules.sys.feedback.dto.req.FeedbackRewardedDTO;
import com.xinqi.modules.sys.feedback.dto.rsp.FeedbackResultDTO;
import com.xinqi.modules.sys.feedback.manager.FeedbackManager;
import com.xinqi.modules.sys.feedback.service.FeedbackService;
import com.xinqi.modules.user.user.client.UserClient;
import com.xinqi.modules.user.user.dto.rsp.UserBaseInfoDO;
import com.xinqi.modules.user.user.dto.rsp.UserResultDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户反馈表服务层实现
 *
 * @author: yyzhenn
 * @date: 2023/04/23
 */
@Validated
@Service("feedbackService")
@RequiredArgsConstructor
public class FeedbackServiceImpl implements FeedbackService {
    private final FeedbackConvert feedbackConvert;
    private final FeedbackManager feedbackManager;

    private final ChatRemindContentClient remindContentClient;

    private final UserClient userClient;

    /**
     * 分页查询 用户反馈表数据
     */
    @Override
    @DS("slaver")
    public PageInfo<FeedbackResultDTO> page(Param pageable, FeedbackQueryDTO query) {
        if (CollectionUtil.isEmpty(pageable.getSorts())) {
            //封装排序
            pageable.setOrderByColumn(StringUtils.EMPTY);
            pageable.setIsAsc(StringUtils.EMPTY);
            pageable.setSorts(new ArrayList<>());
            //默认排序
            pageable.getSorts().add("f.create_time,DESC");
        }
        Page<FeedbackResultDTO> page = feedbackManager.findPage(Pages.page(pageable), query);
        return Pages.convert(page);
    }

    /**
     * 根据id查询 用户反馈表数据
     */
    @DS("slaver")
    @Override
    public FeedbackResultDTO findById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), MessageUtils.message("feedback.id.not.blank"));
        return feedbackManager.findById(id);
    }

    /**
     * 管理后台管理员查看反馈详情 -- 修改状态为已查看
     *
     * @Title:
     * @MethodName: infoByAdminAndId
     * [id]
     * @Return com.xinqi.modules.admin.feedback.dto.rsp.FeedbackResultDTO
     * @Exception
     * @Description:
     * @author: yyzhen
     * @date: 2023/4/23 15:29
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FeedbackResultDTO infoByAdminAndId(Long id) {
        FeedbackResultDTO result = Optional.ofNullable(feedbackManager.findById(id))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("data.does.not.exist")));
        if (Objects.equals(YesNoNumberEnum.NO.getCode(), result.getStatus())) {
            LambdaUpdateWrapper<FeedbackEntity> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(FeedbackEntity::getStatus, YesNoNumberEnum.YES.getCode())
                .eq(FeedbackEntity::getId, id);
            feedbackManager.update(updateWrapper);

            result.setStatus(YesNoNumberEnum.YES.getCode());
        }
        return result;
    }

    /**
     * 用户反馈-奖品发放
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean grantFeedback(FeedbackGrantDTO dto) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(dto.getId()), MessageUtils.message("feedback.id.not.blank"));
        FeedbackEntity entity = Optional.ofNullable(feedbackManager.getById(dto.getId()))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException(MessageUtils.message("data.does.not.exist")));
        CommonErrors.BAD_REQUEST.check(Objects.equals(FeedbackModeEnum.REWARDED_FEEDBACK.getCode(), entity.getMode()), MessageUtils.message("feedback.mode.is.valid"));
        CommonErrors.BAD_REQUEST.check(Objects.equals(YesNoNumberEnum.NO.getCode(), entity.getGrant()), MessageUtils.message("feedback.grant.is.valid"));
        //随机奖品
        if (StringUtils.isEmpty(entity.getPrize())) {
            CommonErrors.BAD_REQUEST.check(StringUtils.isNotEmpty(dto.getPrize()), MessageUtils.message("feedback.prize.not.blank"));
            entity.setPrize(dto.getPrize());
        }
        entity.setGrant(YesNoNumberEnum.YES.getCode());
        entity.setGrantUser(dto.getOperationUserId());
        entity.setGrantTime(LocalDateTime.now());

        return feedbackManager.updateById(entity);
    }

    /**
     * 新增普通反馈
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insert(FeedbackCreateDTO dto) {
        FeedbackEntity entity = feedbackConvert.create(dto);
        entity.setMode(FeedbackModeEnum.GENERAL_FEEDBACK.getCode());
        entity.setStatus(YesNoNumberEnum.NO.getCode());
        entity.setGrant(YesNoNumberEnum.NO.getCode());
        entity.setCreateBy(dto.getOperationUserId());
        entity.setCreateTime(LocalDateTime.now());
        feedbackManager.save(entity);
        //新奇提醒机器人 -- 用户反馈
        remindContentClient.insert(new ChatRemindContentCreateDTO(dto.getOperationUserId(), ChatRemindTypeEnum.USER_FEEDBACK, ChatRemindConstants.REMIND_USER_FEEDBACK_TEMPLATE));

        return entity.getId();
    }

    /**
     * 新增有奖反馈
     *
     * @param dto
     * @return
     */
    @Override
    public Long rewarded(FeedbackRewardedDTO dto) {

        FeedbackEntity entity = feedbackConvert.rewarded(dto);

        // 获取用户信息 判断手机号是否已领取过简历
        UserResultDTO user = R.as(userClient.findById(dto.getOperationUserId()));
        List<UserBaseInfoDO> userList = R.as(userClient.getUserBaseInfoContainDelByMobile(user.getMobile()));
        List<Long> userIds = userList.stream().map(v -> v.getId()).collect(Collectors.toList());
        boolean flag = Objects.isNull(feedbackManager.findRewardedFeedbackList(userIds));

        if (Objects.equals(1, user.getUserRole())) {
            // 判断老师 老师第一次有奖反馈 其余普通反馈
            if (flag) {
                entity.setMode(FeedbackModeEnum.REWARDED_FEEDBACK.getCode());
            } else {
                entity.setMode(FeedbackModeEnum.GENERAL_FEEDBACK.getCode());
            }
        } else {
            // 学生永远 普通反馈
            entity.setMode(FeedbackModeEnum.GENERAL_FEEDBACK.getCode());
        }

        entity.setStatus(YesNoNumberEnum.NO.getCode());
        entity.setGrant(YesNoNumberEnum.NO.getCode());
        entity.setCreateBy(dto.getOperationUserId());
        entity.setCreateTime(LocalDateTime.now());
        feedbackManager.save(entity);

        //新奇提醒机器人 -- 用户反馈
        Spring.committedAsync(() -> {
            remindContentClient.insert(new ChatRemindContentCreateDTO(dto.getOperationUserId(), ChatRemindTypeEnum.USER_FEEDBACK, ChatRemindConstants.REMIND_USER_FEEDBACK_TEMPLATE));
        });
        return entity.getId();
    }

    /**
     * 校验是否是有奖反馈（首次反馈才可以）
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean checkRewarded(Long userId) {
        UserResultDTO user = R.as(userClient.findById(userId));
        if (Objects.equals(1, user.getUserRole())) {
            List<UserBaseInfoDO> userList = R.as(userClient.getUserBaseInfoContainDelByMobile(user.getMobile()));
            List<Long> userIds = userList.stream().map(v -> v.getId()).collect(Collectors.toList());
            return Objects.isNull(feedbackManager.findRewardedFeedbackList(userIds));
        } else {
            return false;
        }
    }

    /**
     * 根据id删除 用户反馈表数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), MessageUtils.message("feedback.id.not.blank"));
        return feedbackManager.removeById(id);
    }

    /**
     * 根据id删除 用户反馈表数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(FeedbackDeleteDTO dto) {
        return deleteById(dto.getId());
    }

}
